package com.plantplaces.service;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;

import com.plantplaces.dao.IOfflinePlantDAO;
import com.plantplaces.dao.IPlantDAO;
import com.plantplaces.dao.OfflinePlantDAO;
import com.plantplaces.dao.PlantDAOImpl;
import com.plantplaces.dto.Plant;
import com.plantplaces.dto.PlantSearch;

/**
 * Integration layer.  Coordinates activities with data sources through DAO layer.
 * Handles creating and retreiving from least recently used cache.
 * 
 * @author jonesbr
 *
 */
public class PlantService implements IPlantService {
	
	// reference to persistence layer.
	IPlantDAO onlinePlantDAO;
	IOfflinePlantDAO offlinePlantDAO;
	
	/**
	 * Because the constuctor is invoked when we create an object, it's a great place to initialize things.
	 */
	public PlantService(Context ctx) {
		onlinePlantDAO = new PlantDAOImpl();
		offlinePlantDAO = new OfflinePlantDAO(ctx);
	}
	
	/* (non-Javadoc)
	 * @see com.plantplaces.service.IPlantService#fetchPlants(com.plantplaces.dto.PlantSearch)
	 */
	@Override
	public List<Plant> fetchPlants(PlantSearch ps) {
		// Create the return type.
		List<Plant> allPlants = new ArrayList<Plant>();
		
		// seemless online/offline toggle.
		try {
			// if we are connected to the network, this will give us live results.
			allPlants = onlinePlantDAO.fetchPlants(ps);
			
			// create an object of the inner class that will store these data locally.
			LocalDataCache ldc = new LocalDataCache(allPlants);
			// create a new Thread class.
			Thread t = new Thread(ldc);
			// start the new thread.
			t.start();
		} catch (Exception e) {
			// if we are not online, an exception will be thrown above and caught here.  
			// So if we're here, we know that we are offline.  Try to get the plants from local data
			try {
				// get the offline data. 
				allPlants = offlinePlantDAO.fetchPlants(ps);
			} catch (Exception e1) {
				// If we can get online or offline data, just ignore and return an empty list.
				e1.printStackTrace();
			}
		}
		
		// return the data.
		return allPlants;
	}

	class LocalDataCache implements Runnable {

		List<Plant> allPlants;
				
		public LocalDataCache(List<Plant> allPlants) {
			this.allPlants = allPlants;
		}
		
		@Override
		public void run() {
			// save the data locally as we read it.
			try {
				offlinePlantDAO.insert(allPlants);
			} catch (Exception e) {
				// If we get an exception here, it's not critical.  We'll just save the plants next time.
				e.printStackTrace();
			}
		}
		
	}
	
}
